﻿using ComLib.ComType;
using DeviceCommon;
using LogLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Threading;

namespace PassportReader
{
    public class PassportReader : DeviceBase
    {
        private PRSDK _sdk = new PRSDK();
        // <summary>
        /// 设置读取护照类型的SDK识别ID
        /// </summary>
        public const int PassportID = 13;

        /// <summary>
        /// 设置读取签证类型的SDK识别ID
        /// </summary>
        public const int VisaID = 12;

        /// <summary>
        /// 当前待识别证件的类型
        /// </summary>
        private int CurrentIDCardType = 13;

        /// <summary>
        /// 检测放本状态的轮询时间(ms)
        /// </summary>
        private const int _readInterval = 250;

        /// <summary>
        /// 读本失败的重试次数
        /// </summary>
        public const int RetryTimes = 3;

        /// <summary>
        /// 护照类型，台胞证或外国人
        /// </summary>
        private string PassportType = "Foreign";

        //private bool _bExit = false;
        private string _imageFilePath = "";
        private Polling poll = null;

        /// <summary>
        /// 阅读器选项
        /// </summary>
        protected PassportReaderOption _option = new PassportReaderOption();
        public PassportReaderOption Option
        {
            get { return _option; }
            set { _option = value; }
        }

        public PassportReader()
        {
            LoadConfig();
        }

        private void LoadConfig()
        {
            if (!File.Exists(_option.ConfigFilePath))
            {
                _option.Save();
            }
            _option.Load();
            Log.WriteAsync(_option.ToString());
        }



        public override bool DoAction(string param, out string outParam)
        {
            return DetectingAndReading(param, out outParam);
        }

        public override void Exit(string inParams, out string outParam)
        {
            outParam = "";
            try
            {
                _sdk.FreeKernal();
                _bExited = true;
                _state = DeviceState.NotInitialized;
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
            finally
            {
                _bInited = false;
            }
        }

        public override void Init(string inParam, out string outParam)
        {
            Log.WriteAsync(string.Format("开始初始化护照阅读机"));
            outParam = "";
            if (_sdk.LoadKernal(_option.DllDir, _option.UserId))
            {
                Log.WriteAsync(string.Format("护照阅读机初始化成功"));
                _bInited = true;
                //_bExit = false;                
            }
            else
            {
                outParam = string.Format("护照阅读机初始化失败: {0}", _sdk.ErrorMessage);
                Log.WriteAsync(outParam);
                _bInited = false;
                //_bExit = true;               
            }
        }

        public override void ShowConfigDialog(string inParam)
        {
           
        }

        private bool DetectingAndReading(string inParams, out string outParam)
        {
            outParam = "";
            Log.WriteAsync("进入DetectPassportAndRead线程"); 
            if (!_sdk.CheckDeviceConnected())            
            {
                outParam = "设备未连接";
                Log.WriteAsync(outParam);               
                return false; 
            }
            
                int existsFlag = 0;
                if (!_sdk.CheckExistDocument(ref existsFlag))
                {
                    // 2表示证件被拿出
                    // 0表示无信号，一般发生在证件刚被取走的瞬间
                    // 1表示有信号
                    if (existsFlag == 0
                        || existsFlag == 2
                        || existsFlag == 3)
                    {
                        return false;

                    }
                }

            bool ret =  OnReading(CurrentIDCardType, out outParam);
            if (ret)
            {
                outParam = GetCardInfoString(outParam);
            }
           
            Log.WriteAsync("离开DetectPassportAndRead线程");

            return ret;
        }

        private string GetCardInfoString(string recogRet)
        {
            JObject param = JObject.Parse(recogRet);
            IDCardAll info = new IDCardAll();
            //info.address = param["持证人国籍代码"].ToString();
            //info.sex = param["性别"].ToString();
            //info.birthday = param["出生日期"].ToString();
            //info.signdate = param["签发日期"].ToString();

            string zjhm = (string)param["护照号码MRZ"];
            if(!string.IsNullOrEmpty(zjhm))
            {
                info.number = zjhm;
            }
            else
            {
                zjhm = (string)param["证件号码"];
                info.number = zjhm;
            }
            //info.name = param["本国姓名拼音OCR"].ToString();
            //info.validtermOfStart = param["签发日期"].ToString();
            //info.validtermOfEnd = param["有效期至"].ToString();

            return JsonConvert.SerializeObject(info);
        }

        /// <summary>
        /// 读本动作
        /// </summary>
        /// <returns></returns>
        private bool OnReading(int IDCardType,out string outParam)
        {
            string recogRet;
            outParam = "";
            int i = 0;
            try
            {
                do
                {
                    if (_sdk.ScanAndRecog(IDCardType, _imageFilePath, out recogRet))
                    {
                        Log.WriteAsync("读取成功:" + recogRet);
                        outParam = recogRet;
                        return true;
                    }
                    Log.WriteAsync("识别失败！识别次数=" + (i + 1).ToString());
                    Thread.Sleep(1000);
                } while ((i++) <= RetryTimes + 1); // 读本失败进行重试
            }
            catch (System.Exception ex)
            {
                outParam = ex.ToString();
                Log.WriteAsync("读取完成，结果是失败:" + outParam);
                return false;
            }
            outParam = _sdk.ErrorMessage;
            Log.WriteAsync("读取完成，结果是失败:" + outParam);
            return false;
        }

        public override void Start(string param, out string outParam)
        {
            outParam = null;
            poll = new Polling(DetectingAndReading, param);
            poll.TimeoutMilliSecond = TimeoutMillisecond;
            poll.ScanInterval = _option.ScanInterval;
            poll.Start(OnWorkingCompleted);
        }

        public override void Stop(string param, out string outParam)
        {
            outParam = null;
            if (poll != null)
            {
                poll.Stop();
                poll.Dispose();
                poll = null;
            }
        }

        protected override void OnWorkingCompleted(string outParams)
        {
            base.OnWorkingCompleted(outParams);
        }

        protected override void OnWorkingFailed(string message)
        {
            base.OnWorkingFailed(message);
        }
    }
}
